<template>
	<a-modal
		class="ai-outpainting-modal"
		v-model:open="visible"
		title="AI 智能扩图"
		:footer="false"
		@cancel="closeModal"
		width="800px"
		:style="{ top: '20px' }"
	>
		<!-- 顶部信息栏 -->
		<div class="modal-header">
			<div class="picture-info">
				<a-tag color="blue">{{ picture?.name || '未命名图片' }}</a-tag>
				<a-tag v-if="picture?.picSize" color="green">{{ formatFileSize(picture.picSize) }}</a-tag>
				<a-tag v-if="picture?.picWidth && picture?.picHeight" color="orange">
					{{ picture.picWidth }} × {{ picture.picHeight }}
				</a-tag>
			</div>
		</div>

		<!-- 主体内容区 -->
		<div class="modal-content">
			<a-row :gutter="24">
				<!-- 原图区域 -->
				<a-col :span="12">
					<div class="image-section">
						<div class="section-header">
							<h3>
								<PictureOutlined />
								原图
							</h3>
							<a-tooltip title="支持 JPG、PNG、WEBP 等格式，文件大小不超过 10MB">
								<QuestionCircleOutlined class="help-icon" />
							</a-tooltip>
						</div>
						<div class="image-container original-image">
							<img :src="picture?.url" :alt="picture?.name" @load="handleImageLoad" />
						</div>
						<div class="image-meta">
							<p v-if="picture?.picWidth && picture?.picHeight">
								分辨率：{{ picture.picWidth }} × {{ picture.picHeight }}px
							</p>
							<p v-if="picture?.picSize">文件大小：{{ formatFileSize(picture.picSize) }}</p>
						</div>
					</div>
				</a-col>

				<!-- 结果区域 -->
				<a-col :span="12">
					<div class="image-section">
						<div class="section-header">
							<h3>
								<BgColorsOutlined />
								扩图结果
								<a-tooltip v-if="!!taskId" title="AI 正在智能分析和扩展图片边缘">
									<LoadingOutlined class="loading-icon" />
								</a-tooltip>
							</h3>
							<a-dropdown v-if="resultImageUrl && !taskId" placement="bottomRight">
								<template #overlay>
									<a-menu>
										<a-menu-item key="download" @click="downloadResult">
											<DownloadOutlined />
											下载图片
										</a-menu-item>
										<a-menu-item key="preview" @click="previewResult">
											<EyeOutlined />
											全屏预览
										</a-menu-item>
									</a-menu>
								</template>
								<a-button size="small" type="text">
									<MoreOutlined />
								</a-button>
							</a-dropdown>
						</div>

						<div class="image-container result-image">
							<img v-if="resultImageUrl" :src="resultImageUrl" :alt="picture?.name" class="result-img" />
							<a-empty v-else-if="!taskId" class="empty-state">
								<template #image>
									<BgColorsOutlined class="empty-icon" />
								</template>
								<template #description>
									<span class="empty-text">暂无扩图结果</span>
								</template>
							</a-empty>
							<div v-else class="loading-state">
								<a-spin size="large" class="loading-spinner" />
								<div class="loading-content">
									<h4>AI 正在处理中...</h4>
									<p>正在智能分析图片内容并扩展边缘</p>
									<a-progress :percent="loadingProgress" :show-info="false" stroke-color="#1890ff" />
									<div class="loading-info" v-if="estimatedResultSize">
										<p>预测输出尺寸：{{ estimatedResultSize.width }} × {{ estimatedResultSize.height }}px</p>
										<p v-if="estimatedFileSize">预测文件大小：{{ estimatedFileSize }}</p>
									</div>
								</div>
							</div>
						</div>

						<div v-if="resultImageUrl && !taskId" class="result-meta">
							<p>
								<a-tag color="success">处理完成</a-tag>
								<span class="process-time">耗时：{{ processTime }}秒</span>
							</p>
							<p v-if="estimatedResultSize">
								预测分辨率：{{ estimatedResultSize.width }} × {{ estimatedResultSize.height }}px
							</p>
							<p v-if="estimatedFileSize">预测文件大小：{{ estimatedFileSize }}</p>
							<p>扩展倍数：横向 {{ parameters.xScale }}x，纵向 {{ parameters.yScale }}x</p>
						</div>
					</div>
				</a-col>
			</a-row>
		</div>

		<!-- 底部操作区 -->
		<div class="modal-footer">
			<div class="footer-left">
				<a-tooltip title="AI扩图会智能分析图片内容，自动扩展边缘，保持画面自然">
					<a-typography-text type="secondary" class="tip-text">
						<BulbOutlined /> 提示：AI 会根据图片内容智能扩展边缘区域
					</a-typography-text>
				</a-tooltip>
			</div>
			<div class="footer-right">
				<a-space size="large">
					<a-button size="large" @click="closeModal"> 取消 </a-button>
					<a-button size="large" type="default" @click="showParametersModal" :disabled="!picture?.url">
						<template #icon>
							<SettingOutlined />
						</template>
						设置参数
					</a-button>
					<a-button type="primary" size="large" @click="createTask" :loading="!!taskId" :disabled="!picture?.url">
						<template #icon>
							<BgColorsOutlined v-if="!taskId" />
						</template>
						{{ !!taskId ? '处理中...' : '开始 AI 扩图' }}
					</a-button>
					<a-button
						v-if="resultImageUrl && !taskId"
						type="primary"
						size="large"
						ghost
						:loading="uploadLoading"
						@click="handleUpload"
					>
						<template #icon>
							<CheckOutlined />
						</template>
						应用结果
					</a-button>
				</a-space>
			</div>
		</div>
	</a-modal>

	<!-- 参数设置弹窗 -->
	<a-modal
		v-model:open="parametersVisible"
		title="AI 扩图参数设置"
		width="500px"
		@ok="applyParameters"
		@cancel="parametersVisible = false"
	>
		<a-form :model="tempParameters" layout="vertical" class="params-form">
			<a-alert
				message="扩图参数说明"
				description="根据阿里云AI扩图服务，横向和纵向扩展倍数建议在1.2-2.5之间，可获得最佳效果。"
				type="info"
				show-icon
				style="margin-bottom: 20px"
			/>

			<a-row :gutter="16">
				<a-col :span="12">
					<a-form-item label="横向扩展倍数">
						<a-input-number
							v-model:value="tempParameters.xScale"
							:min="1.2"
							:max="2.5"
							:step="0.1"
							:precision="1"
							style="width: 100%"
							placeholder="1.2-2.5"
						/>
						<div class="param-tip">推荐值：2.0</div>
					</a-form-item>
				</a-col>
				<a-col :span="12">
					<a-form-item label="纵向扩展倍数">
						<a-input-number
							v-model:value="tempParameters.yScale"
							:min="1.2"
							:max="2.5"
							:step="0.1"
							:precision="1"
							style="width: 100%"
							placeholder="1.2-2.5"
						/>
						<div class="param-tip">推荐值：2.0</div>
					</a-form-item>
				</a-col>
			</a-row>

			<a-form-item label="最佳质量模式">
				<a-switch v-model:checked="tempParameters.bestQuality" />
				<div class="param-tip">开启后处理时间更长，但画质更好</div>
			</a-form-item>

			<a-form-item label="限制输出尺寸">
				<a-switch v-model:checked="tempParameters.limitImageSize" />
				<div class="param-tip">避免生成过大的图片文件</div>
			</a-form-item>

			<a-divider orientation="left">预设模式</a-divider>
			<a-space wrap>
				<a-button size="small" @click="loadPreset('light')">轻度扩图 (1.5x)</a-button>
				<a-button size="small" @click="loadPreset('medium')">标准扩图 (2.0x)</a-button>
				<a-button size="small" @click="loadPreset('strong')">强度扩图 (2.5x)</a-button>
			</a-space>

			<a-divider />
			<div class="preview-info">
				<h4>预览信息</h4>
				<p
					v-if="picture?.picWidth && picture?.picHeight && tempParameters.xScale && tempParameters.yScale"
					class="size-info"
				>
					原始尺寸：{{ picture.picWidth }} × {{ picture.picHeight }}px<br />
					预估尺寸：{{ Math.round(picture.picWidth * tempParameters.xScale) }} ×
					{{ Math.round(picture.picHeight * tempParameters.yScale) }}px
				</p>
			</div>
		</a-form>
	</a-modal>
</template>
<script setup lang="ts">
import {
	createPictureOutPaintingTaskUsingPost,
	getPictureOutPaintingTaskUsingGet,
	uploadPictureByUrlUsingPost,
} from '@/api/pictureController'
import { message } from 'ant-design-vue'
import { ref, computed } from 'vue'
import {
	PictureOutlined,
	BgColorsOutlined,
	LoadingOutlined,
	QuestionCircleOutlined,
	DownloadOutlined,
	EyeOutlined,
	MoreOutlined,
	CheckOutlined,
	BulbOutlined,
	SettingOutlined,
} from '@ant-design/icons-vue'

interface Props {
	picture?: API.PictureVO
	spaceId?: any
	onSuccess?: (newPicture: API.PictureVO) => void
}

const props = defineProps<Props>()

// AI扩图参数 - 简化版，符合阿里云要求
const parameters = ref<API.Parameters>({
	xScale: 2.0,
	yScale: 2.0,
	bestQuality: true,
	limitImageSize: true,
})

// 参数弹窗控制
const parametersVisible = ref<boolean>(false)
const tempParameters = ref<API.Parameters>({ ...parameters.value })

const resultImageUrl = ref<string>('')
const loadingProgress = ref<number>(0)
const processTime = ref<number>(0)
const startTime = ref<number>(0)

// 任务 ID
const taskId = ref<string>('')

// 计算预测结果尺寸
const estimatedResultSize = computed(() => {
	if (!props.picture?.picWidth || !props.picture?.picHeight || !parameters.value.xScale || !parameters.value.yScale) {
		return null
	}
	return {
		width: Math.round(props.picture.picWidth * parameters.value.xScale),
		height: Math.round(props.picture.picHeight * parameters.value.yScale),
	}
})

// 计算预测文件大小
const estimatedFileSize = computed(() => {
	if (!props.picture?.picSize || !parameters.value.xScale || !parameters.value.yScale) {
		return null
	}
	// 根据扩展倍数估算文件大小增长（通常会比面积增长稍小，因为压缩算法的特性）
	const areaMultiplier = parameters.value.xScale * parameters.value.yScale
	const estimatedSize = Math.round(props.picture.picSize * areaMultiplier * 0.8) // 0.8是经验系数
	return formatFileSize(estimatedSize)
})

// 工具函数
const formatFileSize = (size: number | undefined): string => {
	if (!size) return '未知大小'
	if (size < 1024) return size + ' B'
	if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
	return (size / (1024 * 1024)).toFixed(1) + ' MB'
}

const handleImageLoad = () => {
	console.log('Original image loaded')
}

// 参数弹窗相关方法
const showParametersModal = () => {
	tempParameters.value = { ...parameters.value }
	parametersVisible.value = true
}

const applyParameters = () => {
	parameters.value = { ...tempParameters.value }
	parametersVisible.value = false
	message.success('参数设置已应用')
}

// 预设参数加载
const loadPreset = (type: 'light' | 'medium' | 'strong') => {
	const presets = {
		light: {
			xScale: 1.5,
			yScale: 1.5,
			bestQuality: false,
			limitImageSize: true,
		},
		medium: {
			xScale: 2.0,
			yScale: 2.0,
			bestQuality: true,
			limitImageSize: true,
		},
		strong: {
			xScale: 2.5,
			yScale: 2.5,
			bestQuality: true,
			limitImageSize: false,
		},
	}

	tempParameters.value = { ...tempParameters.value, ...presets[type] }
	const presetNames = { light: '轻度', medium: '标准', strong: '强度' }
	message.success(`已应用${presetNames[type]}扩图预设`)
}

const downloadResult = () => {
	if (!resultImageUrl.value) return
	const link = document.createElement('a')
	link.href = resultImageUrl.value
	link.download = `ai-outpainted-${props.picture?.name || 'image'}.jpg`
	document.body.appendChild(link)
	link.click()
	document.body.removeChild(link)
	message.success('开始下载结果图片')
}

const previewResult = () => {
	if (!resultImageUrl.value) return
	window.open(resultImageUrl.value, '_blank')
}

// 创建扩图任务
const createTask = async () => {
	if (!props.picture?.id) {
		message.error('请先上传图片')
		return
	}

	// 验证参数合理性
	if (parameters.value.xScale! < 1.2 || parameters.value.xScale! > 2.5) {
		message.error('横向扩展倍数应在1.2-2.5之间')
		return
	}
	if (parameters.value.yScale! < 1.2 || parameters.value.yScale! > 2.5) {
		message.error('纵向扩展倍数应在1.2-2.5之间')
		return
	}

	startTime.value = Date.now()
	loadingProgress.value = 0

	try {
		const res = await createPictureOutPaintingTaskUsingPost({
			pictureId: props.picture.id,
			parameters: {
				xScale: parameters.value.xScale,
				yScale: parameters.value.yScale,
				bestQuality: parameters.value.bestQuality,
				limitImageSize: parameters.value.limitImageSize,
			},
		})
		if (res.data.code === 0 && res.data.data) {
			message.success('AI扩图任务已创建，正在处理中...')
			taskId.value = res.data.data.output?.taskId || ''
			startPolling()
		} else {
			message.error('扩图任务创建失败：' + res.data.message)
		}
	} catch (error: any) {
		console.error('创建扩图任务失败', error)
		message.error('创建扩图任务失败：' + error.message)
	}
}

// 轮询获取扩图结果
let pollingTimer: number | null = null
let progressTimer: number | null = null

// 开始轮询
const startPolling = () => {
	if (!taskId.value) {
		return
	}
	if (pollingTimer) clearInterval(pollingTimer)
	if (progressTimer) clearInterval(progressTimer)

	// 进度条模拟
	progressTimer = setInterval(() => {
		if (loadingProgress.value < 90) {
			loadingProgress.value += Math.random() * 10
		}
	}, 1000)

	pollingTimer = setInterval(async () => {
		try {
			const res: any = await getPictureOutPaintingTaskUsingGet({
				taskId: taskId.value,
			})
			if (res.data.code === 0 && res.data.data) {
				console.log('轮询获取扩图结果', res.data.data)
				const taskResult = res.data.data.output
				if (taskResult.taskStatus === 'SUCCEEDED') {
					loadingProgress.value = 100
					processTime.value = Math.round((Date.now() - startTime.value) / 1000)
					message.success('扩图任务执行成功！')
					resultImageUrl.value = taskResult.outputImageUrl || ''
					// 清理轮询
					clearPolling()
				} else if (taskResult.taskStatus === 'FAILED') {
					message.error('扩图任务执行失败，' + taskResult.message)
					// 清理轮询
					clearPolling()
				}
			}
		} catch (error) {
			console.error('获取扩图结果失败', error)
			message.error('获取扩图结果失败，请稍后重试')
			// 清理轮询
			clearPolling()
		}
	}, 3000) // 每 3 秒轮询一次
}

// 清理轮询
const clearPolling = () => {
	if (pollingTimer) {
		clearInterval(pollingTimer)
		pollingTimer = null
	}
	if (progressTimer) {
		clearInterval(progressTimer)
		progressTimer = null
	}
	taskId.value = ''
}

const uploadLoading = ref<boolean>(false)
// 图片上传操作
const handleUpload = async () => {
	uploadLoading.value = true
	try {
		// 调用上传接口
		const params: API.PictureUploadRequest = {
			fileUrl: resultImageUrl.value,
			spaceId: props.spaceId,
		}
		if (props.picture) {
			params.id = props.picture.id
		}

		const res = await uploadPictureByUrlUsingPost(params)
		if (res.data.code === 0 && res.data.data) {
			message.success('图片上传成功')
			// 将上传图片成功的信息传递给父组件
			props.onSuccess?.(res.data.data)
			// 关闭弹窗
			closeModal()
		} else {
			message.error('图片上传失败，' + res.data.message)
		}
	} catch (error: any) {
		console.error('图片上传失败', error)
		message.error('图片上传失败：' + error.message)
	}
	uploadLoading.value = false
}

const visible = ref<boolean>(false)

const openModal = () => {
	visible.value = true
}

const closeModal = () => {
	visible.value = false
	// 清理轮询和重置状态
	clearPolling()
	resultImageUrl.value = ''
	loadingProgress.value = 0
	processTime.value = 0
}

// 暴露函数给父组件
defineExpose({
	openModal,
	closeModal,
})
</script>

<style scoped>
.ai-outpainting-modal {
	:deep(.ant-modal) {
		max-width: 800px;
	}

	:deep(.ant-modal-content) {
		border-radius: 12px;
		overflow: hidden;
	}

	:deep(.ant-modal-header) {
		padding: 20px 24px 16px;
		border-bottom: 1px solid #f0f0f0;
		background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
		color: white;

		.ant-modal-title {
			color: white;
			font-size: 18px;
			font-weight: 600;
		}
	}

	:deep(.ant-modal-close) {
		color: white;

		&:hover {
			color: rgba(255, 255, 255, 0.8);
		}
	}

	:deep(.ant-modal-body) {
		padding: 0;
	}
}

.modal-header {
	padding: 16px 24px;
	background: #fafafa;
	border-bottom: 1px solid #f0f0f0;

	.picture-info {
		display: flex;
		gap: 8px;
		align-items: center;
	}
}

.modal-content {
	padding: 24px;
}

/* 参数设置弹窗样式 */
.params-form {
	.param-tip {
		font-size: 12px;
		color: #999;
		margin-top: 4px;
	}

	.preview-info {
		background: #f5f5f5;
		padding: 12px;
		border-radius: 6px;

		h4 {
			margin: 0 0 8px 0;
			color: #333;
			font-size: 14px;
		}

		.size-info {
			margin: 0;
			font-size: 12px;
			color: #666;
			line-height: 1.6;
		}
	}
}

.image-section {
	background: white;
	border-radius: 8px;
	overflow: hidden;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

	.section-header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 16px 20px;
		background: #fafafa;
		border-bottom: 1px solid #f0f0f0;

		h3 {
			margin: 0;
			font-size: 16px;
			font-weight: 600;
			display: flex;
			align-items: center;
			gap: 8px;
			color: #333;
		}

		.help-icon,
		.loading-icon {
			color: #999;
			font-size: 14px;
		}

		.loading-icon {
			color: #1890ff;
			animation: spin 1s linear infinite;
		}
	}

	.image-container {
		position: relative;
		min-height: 300px;
		display: flex;
		align-items: center;
		justify-content: center;
		padding: 20px;

		img {
			max-width: 100%;
			max-height: 400px;
			border-radius: 6px;
			box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
			transition: transform 0.3s ease;

			&:hover {
				transform: scale(1.02);
			}
		}

		&.original-image {
			background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
		}

		&.result-image {
			background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
		}

		.empty-state {
			width: 100%;

			.empty-icon {
				font-size: 48px;
				color: #d9d9d9;
			}

			.empty-text {
				color: #999;
				font-size: 14px;
			}
		}

		.loading-state {
			display: flex;
			flex-direction: column;
			align-items: center;
			gap: 16px;
			width: 100%;

			.loading-spinner {
				:deep(.ant-spin-dot) {
					font-size: 32px;
				}
			}

			.loading-content {
				text-align: center;

				h4 {
					margin: 0 0 8px 0;
					color: #333;
					font-size: 16px;
				}

				p {
					margin: 0 0 16px 0;
					color: #666;
					font-size: 14px;
				}

				:deep(.ant-progress) {
					width: 200px;
				}

				.loading-info {
					margin-top: 16px;
					padding-top: 12px;
					border-top: 1px solid #f0f0f0;

					p {
						margin: 4px 0;
						font-size: 12px;
						color: #999;
					}
				}
			}
		}
	}

	.image-meta,
	.result-meta {
		padding: 16px 20px;
		background: #fafafa;

		p {
			margin: 4px 0;
			font-size: 14px;
			color: #666;
		}

		.process-time {
			margin-left: 8px;
			color: #52c41a;
		}

		:deep(.ant-descriptions) {
			.ant-descriptions-item-label {
				background: #f5f5f5;
				font-weight: 500;
			}

			.ant-descriptions-item-content {
				background: white;
			}
		}
	}
}

.modal-footer {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 16px 24px;
	background: #fafafa;
	border-top: 1px solid #f0f0f0;

	.footer-left {
		.tip-text {
			font-size: 12px;
			display: flex;
			align-items: center;
			gap: 4px;
		}
	}

	.footer-right {
		display: flex;
		gap: 12px;
	}
}

@keyframes spin {
	from {
		transform: rotate(0deg);
	}
	to {
		transform: rotate(360deg);
	}
}

/* 响应式设计 */
@media (max-width: 1200px) {
	.ai-outpainting-modal :deep(.ant-modal) {
		max-width: 95vw;
		margin: 10px;
	}

	.modal-content {
		padding: 16px;
	}

	.image-container {
		min-height: 250px;

		img {
			max-height: 300px;
		}
	}
}

@media (max-width: 768px) {
	.modal-content :deep(.ant-row) {
		flex-direction: column;
	}

	.modal-content :deep(.ant-col) {
		width: 100% !important;
		margin-bottom: 16px;
	}

	.modal-footer {
		flex-direction: column;
		gap: 12px;
		align-items: stretch;

		.footer-left {
			order: 2;
			text-align: center;
		}

		.footer-right {
			order: 1;
			justify-content: center;
			flex-wrap: wrap;
		}
	}
}
</style>
